package com.yunchao.test.presentation.screen

import android.os.Bundle
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import by.kirich1409.viewbindingdelegate.viewBinding
import com.seuic.scankey.IKeyEventCallback
import com.seuic.scankey.ScanKeyService
import com.xuexiang.xui.utils.WidgetUtils
import com.yunchao.feature.base.presentation.activity.BaseActivity
import com.yunchao.feature.base.presentation.ext.hideLoadingDialog
import com.yunchao.feature.base.presentation.ext.setDebouncedClickListener
import com.yunchao.feature.base.presentation.ext.showLoadingDialog
import com.yunchao.feature.base.presentation.ext.showSingleChoiceDialog
import com.yunchao.feature.base.presentation.ext.toast
import com.yunchao.library.lock.LockEPCInfo
import com.yunchao.library.lock.getLockStatusStr
import com.yunchao.library.lock.getVoucherTypeValue
import com.yunchao.test.R
import com.yunchao.test.databinding.ActivityMainBinding
import com.yunchao.test.domain.model.LockToolModel
import com.yunchao.test.domain.model.VoucherTypeModel
import com.yunchao.test.domain.model.voucherTypeList
import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import timber.log.Timber
import kotlin.getValue

internal class MainActivity : BaseActivity(R.layout.activity_main) {

    private val binding: ActivityMainBinding by viewBinding()
    private val viewModel: MainViewModel by viewModel()
    private val scanKeyService: ScanKeyService by inject()
    private val mainAdapter: MainAdapter by lazy { MainAdapter() }
    private var lockEPCInfo: LockEPCInfo? = null
    private var voucherTypeModel: VoucherTypeModel? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(R.style.Theme_YC_HFED_guangdong_Projects)
        scanKeyService.registerCallback(mCallback, "250")
        super.onCreate(savedInstanceState)
        binding.lockLogRecyclerView.apply {
            WidgetUtils.initRecyclerView(this)
            adapter = mainAdapter
        }
        binding.openLockLogisticsBtn.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.openLockWriteLogistics(
                    this
                )
            } ?: run { toast("请先扫描锁信息") }
        }
        binding.closeLockLogisticsBtn.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.closeLockWriteLogistics(
                    this
                )
            } ?: run { toast("请先扫描锁信息") }
        }
        binding.openLockBtn.setDebouncedClickListener { lockEPCInfo?.apply { viewModel.openLock(this) } }
        binding.closeLockBtn.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.closeLock(
                    this
                )
            } ?: run { toast("请先扫描锁信息") }
        }
        binding.clearLockLogBtn.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.cleanLock(
                    this
                )
            } ?: run { toast("请先扫描锁信息") }
        }
        binding.recoveryLockBtn.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.recoveryLock(
                    this
                )
            } ?: run { toast("请先扫描锁信息") }
        }
        binding.overButton.setDebouncedClickListener {
            showSingleChoiceDialog(
                title = "选择面额",
                items = voucherTypeList.map { it.voucherName },
                selectedIndex = 0
            ) {
                voucherTypeModel = voucherTypeList[it].apply {
                    binding.overButton.text = voucherName
                }
            }
        }

        binding.activeButton.setDebouncedClickListener {
            voucherTypeModel?.apply {
                lockEPCInfo?.let {
                    viewModel.activeLock(lockEPCInfo = it, voucherTypeModel = this)
                }
            } ?: run { toast("请先选择面额") }
        }

        binding.queryLockLogBtn.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.readLockLogisticsLog(this)
            } ?: run { toast("请先扫描锁信息") }
        }
        binding.lockLogCountBtn.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.readLockLogCount(this)
            } ?: run { toast("请先扫描锁信息") }
        }
        binding.button.setDebouncedClickListener {
            lockEPCInfo?.apply {
                viewModel.readLockLog(
                    this,
                    binding.lockLogStartTV.centerEditValue.toInt(),
                    binding.lockLogNumberTV.centerEditValue.toInt()
                )
            } ?: run { toast("请先扫描锁信息") }
        }

        binding.startButton.setDebouncedClickListener {
            lockEPCInfo?.apply {
                if (binding.startButton.text == getString(com.yunchao.feature.base.R.string.开始操作)) {
                    binding.startButton.setText(com.yunchao.feature.base.R.string.结束操作)
                    viewModel.loopOpenCloseLock(this)
                } else {
                    binding.startButton.setText(com.yunchao.feature.base.R.string.开始操作)
                    viewModel.stopLoopOpenCloseLock()
                }
            } ?: run { toast("请先扫描锁信息") }
        }

        binding.imageView.setDebouncedClickListener {
            viewModel.getMaintenanceFileList()
        }

        lifecycleScope.launch { viewModel.uiStateFlow.collect(::render) }
        lifecycleScope.launch { viewModel.uiEffectFlow.collect(::effect) }
    }

    private fun render(state: MainViewModel.UiState) {
        when (state) {
            is MainViewModel.UiState.Idle -> Unit
            is MainViewModel.UiState.Content -> updatePageInfo(state.data)
        }
    }

    private fun updatePageInfo(model: LockToolModel) {
        Timber.d("updatePageInfo: $model")
        lockEPCInfo = model.handleAfterLockEPCInfo ?: model.handleBeforeLockEPCInfo
        mainAdapter.submitList(model.lockLogList)
        binding.lockEPCId.text = getString(com.yunchao.feature.base.R.string.锁号STR, lockEPCInfo?.id)
        binding.lockEPC.text = getString(com.yunchao.feature.base.R.string.EPCSTR, lockEPCInfo?.epc)
        binding.lockEPCStatus.text = getString(com.yunchao.feature.base.R.string.锁状态STR, lockEPCInfo?.getLockStatusStr())
        binding.lockEPCVal.text = getString(com.yunchao.feature.base.R.string.锁面额STR, lockEPCInfo?.getVoucherTypeValue())
        binding.errorName.text = getString(com.yunchao.feature.base.R.string.ErrorDest, lockEPCInfo?.tId)
        binding.errorCode.text = getString(com.yunchao.feature.base.R.string.ErrorCode, lockEPCInfo?.lockErrorCode)
        binding.errorDest.text = getString(com.yunchao.feature.base.R.string.锁验证结果STR, lockEPCInfo?.lockAuthResult)
        binding.lockLogTotalNumber.setRightString("${model.loggerTotalCount}")
    }

    private fun effect(effect: MainViewModel.UiEffect) {
        when (effect) {
            is MainViewModel.UiEffect.ShowToast -> hideLoadingDialog().apply { toast(effect.msg, length = Toast.LENGTH_LONG) }
            is MainViewModel.UiEffect.ShowLoading -> showLoadingDialog()
            is MainViewModel.UiEffect.HideLoading -> hideLoadingDialog()
            is MainViewModel.UiEffect.FileList -> showSingleChoiceDialog(
                title = "选择文件",
                items = effect.list.map { it.name },
                selectedIndex = 0
            ) {
                viewModel.handleMaintenanceFile(effect.list[it].name)
            }
        }
    }

    override fun onStart() {
        super.onStart()
        viewModel.openDevice()
    }

    override fun onStop() {
        super.onStop()
        viewModel.closeDevice()
    }

    override fun onDestroy() {
        scanKeyService.unregisterCallback(mCallback)
        super.onDestroy()
    }

    private val mCallback: IKeyEventCallback = object : IKeyEventCallback.Stub() {
        override fun onKeyDown(p0: Int) {
            viewModel.inventoryOnce()
        }

        override fun onKeyUp(p0: Int) {}

    }
}